package com.springboot.service.impl;

import com.springboot.constant.ExamineExecl;
import com.springboot.constant.HealthRecordExecl;
import com.springboot.dto.ExamineDTO;
import com.springboot.entity.Examine;
import com.springboot.entity.HealthRecord;
import com.springboot.entity.WxUser;
import com.springboot.enums.ErrorEnum;
import com.springboot.enums.ExamineStatus;
import com.springboot.exception.MyException;
import com.springboot.repository.ExamineRepository;
import com.springboot.repository.WxUserRepository;
import com.springboot.service.ExamineService;
import com.springboot.utils.ExeclUtil;
import com.springboot.vo.ExamineVO;
import com.springboot.vo.PageVO;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.validation.Errors;

import javax.crypto.ExemptionMechanism;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @descrition:
 * @author: lzh
 */
@Service
public class ExamineServiceImpl implements ExamineService {

    @Autowired
    ExamineRepository examineRepository;

    @Autowired
    WxUserRepository wxUserRepository;

    @Override
    public ExamineVO addExamine(ExamineDTO examineDTO) {
        Page<Examine> page = examineRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            Predicate wxUserId = criteriaBuilder.equal(root.get("wxUserId"), examineDTO.getWxUserId());
            criteriaQuery.orderBy(criteriaBuilder.desc(root.get("id")));
            return criteriaBuilder.and(wxUserId);
        }, PageRequest.of(0, 1));
        if(page.getContent().size() != 0) {
            Examine examine = page.getContent().get(0);
            if(!examine.getStatus().equals(ExamineStatus.NO_PASS_EXAMINE.getCode())) {
                throw new MyException(ErrorEnum.EXAMINE_EXIST);
            }
        }
        Examine examine = new Examine();
        BeanUtils.copyProperties(examineDTO, examine);
        examine.setStatus(ExamineStatus.WAIT_EXAMINE.getCode());
        Examine save = examineRepository.save(examine);
        ExamineVO examineVO = new ExamineVO();
        BeanUtils.copyProperties(examine, examineVO);
        return examineVO;
    }

    @Override
    public ExamineVO findExamine(Integer wxUserId) {
        Page<Examine> page = examineRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            Predicate predicate = criteriaBuilder.equal(root.get("wxUserId"), wxUserId);
            criteriaQuery.orderBy(criteriaBuilder.desc(root.get("id")));
            return criteriaBuilder.and(predicate);
        }, PageRequest.of(0, 1));
        if(page.getContent().size() == 0) {
            throw new MyException(ErrorEnum.GET_EXAMINE_ERROR);
        }
        Examine examine = page.getContent().get(0);
        ExamineVO examineVO = new ExamineVO();
        BeanUtils.copyProperties(examine, examineVO);
        return examineVO;
    }

    @Override
    public PageVO getExamineList(Integer pageNum, Integer pageSize, ExamineStatus status) {
        Page<Examine> page = examineRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            if (status != null) {
                list.add(criteriaBuilder.equal(root.get("status"), status.getCode()));
            }
            criteriaQuery.orderBy(criteriaBuilder.desc(root.get("time")));
            return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
        }, PageRequest.of(pageNum - 1, pageSize));
        PageVO pageVO = PageVO.convert(page);
        List<ExamineVO> examineVOList = page.getContent().stream().map(examine -> {
            ExamineVO examineVO = new ExamineVO();
            BeanUtils.copyProperties(examine, examineVO);
            return examineVO;
        }).collect(Collectors.toList());
        pageVO.setContent(examineVOList);
        return pageVO;
    }

    @Override
    public void editExamine(Integer id, Integer flag) {
        Examine one = examineRepository.getOne(id);
        if((flag != 1 && flag != 2) || one.getStatus() != 0) {
            throw new MyException(ErrorEnum.EDIT_EXAMINE_ERROR);
        }
        one.setStatus(flag);
        examineRepository.save(one);
        WxUser wxUser = wxUserRepository.getOne(one.getWxUserId());
        wxUser.setName(one.getName());
        wxUser.setIdCard(one.getIdCard());
        wxUser.setIsRegident(one.getIsRegident());
        wxUser.setRoomNumber(one.getRoomNumber());
        wxUserRepository.save(wxUser);
    }

    @Override
    public HSSFWorkbook dowloadExecl() {
        List<Examine> examineList = examineRepository.findAll();
        List<List<String>> values = new ArrayList<>();
        for (Examine examine : examineList) {
            List<String> value = new ArrayList<>();
            value.add(examine.getName());
            value.add(examine.getIdCard());
            value.add(examine.getIsRegident() ? "住户" : "外来人员");
            value.add(examine.getRoomNumber());
            value.add(String.valueOf(examine.getTime()));
            if(examine.getStatus().equals(ExamineStatus.WAIT_EXAMINE.getCode())) {
                value.add(ExamineStatus.WAIT_EXAMINE.getMsg());
            } else if(examine.getStatus().equals(ExamineStatus.PASS_EXAMINE.getCode())) {
                value.add(ExamineStatus.PASS_EXAMINE.getMsg());
            } else {
                value.add(ExamineStatus.NO_PASS_EXAMINE.getMsg());
            }
            values.add(value);
        }
        return ExeclUtil.getHSSFWorkbook(ExamineExecl.SHEETNAME
                , ExamineExecl.TITLES, values);
    }
}
